

#include "unity.h"
#include "unity_fixture.h"

#include "Debug.h"
#include "BSP_Sleep.h"
#include "log/log2.h"

#include "FreeRTOS.h"
#include "task.h"

#include <phNfcLib_Initialization.h>
#include "Utility.h"
#include <Reader/Reader.h>
#include <Reader/ReaderDesfire2.h>
#include <Reader/apple_epc.h>
#include "phDriver.h"

/*=============================================================*/
/*
get_uid_app_key : 50801750E819E5D2B2BD772E90D8AFF3
get_uid_app_key_id: 00
get_uid_app_id : F568A0
get_uid_file_id : 00
File_size : 7 bytes

User_id_app_key: 39949D07A573E66920A082BABB58C179
User_id_app_key_id : 00
User_id_app_id : F569A0
User_id_file_id : 00
File_size : 5 bytes


Desfire Settings
card_master_key
app_master_key
diversification_key
file_read_key
app_id
file_id
file_size
Card Master Key: 50801750E819E5D2B2BD772E90D8AFF3
Application Master Key: 39949D07A573E66920A082BABB58C179
Diversification (NXP AN10922, slightly modified, please check provided cmac_test.py):
E795EB10BFAAD62994547938FB0CE46E77098167
File Read Key: 48C9DEC5BD43F1C03D2AC37B09842951
Application ID: F567A0
UID is open, anyone can read it.
File ID to Read: 0
File Size: 5 bytes
*/



//获取分散因子
static int reader_switflane_read_uid(uint8_t* div, uint8_t* dlen){
		int ret;
	//2. SELECT the Privacy application and authenticate using the undiversified key.
#if 1
		uint8_t aid[3] = {0xF5,0x69,0xA0};
		ret = Reader_MFDF_SelectApplication(PHAL_MFDFEVX_SELECT_PRIMARY_APP, (uint8_t*)aid, NULL);
		if(ret){
			LOG2_ERR("select app(%02X%02X%02X) fail: %04X", aid[0],aid[1],aid[2], ret);
			return 1;
		}
#endif 
#if 1		
	//3. Read the static UID/CSN of the credential following Privacy app authentication.
		uint8_t keyNo = 1;		
		uint8_t ver = 0;
		void* key_store = phNfcLib_GetDataParams(PH_COMP_KEYSTORE);
		//E795EB10BFAAD62994547938FB0CE46E77098167
		uint8_t key_div[] = { 0xE7,0x95,0xEB,0x10,0xBF,0xAA, 0xD6,0x29,0x94,0x57,0x93,0x8F,0xB0,0xCE,0x46,0xE7,0x70,0x98,0x16 };

		uint8_t master_key[16] = { 0x50,0x80,0x17,0x50,0xE8,0x19,0xE5,0xD2,0xB2,0xBD,0x77,0x2E,0x90,0xD8,0xAF,0xF3 };

		//get_uid_app_key : 39949D07A573E66920A082BABB58C179
		uint8_t app_key[16] = { 0x39,0x94,0x9D,0x07,0xA5,0x73,0xE6,0x69,0x20,0xA0,0x82,0xBA,0xBB,0x58,0xC1,0x79 };
		//uint8_t app_key[16] = { 0x39, 0x94, 0x9D, 0x07, 0xA5, 0x73, 0xE6, 0x69, 0x20, 0xA0, 0x82, 0xBA, 0xBB, 0x58, 0xC1, 0x79 };		
		uint8_t key_type = PH_KEYSTORE_KEY_TYPE_AES128;
		uint8_t key_no_card = 0;
		uint8_t* key = app_key;
		phKeyStore_FormatKeyEntry(key_store, keyNo, key_type);
		// phKeyStore_SetKeyAtPos(key_store, keyNo, 0, key_type, master_key, ver);
		phKeyStore_SetKeyAtPos(key_store, keyNo, 0, key_type, key, ver);
		ret = Reader_MFDF_AuthenticateAES(PHAL_MFDFEVX_NO_DIVERSIFICATION, keyNo, ver, key_no_card, NULL, 0);
		if(ret){
			LOG2_ERR("auth fail: %04X", ret);
			return 2;
		}
#endif			

	uint8_t bFileNo = 0;
	uint8_t olen = 5;
	uint8_t *data = NULL;
	uint16_t rlen = 0;
	uint8_t offset[3] = {0x00, 0x00, 0x00};
	uint8_t length[3] = {olen, 0x00, 0x00};
	ret = Reader_MFDF_ReadData(PHAL_MFDFEVX_COMMUNICATION_ENC, PHAL_MFDFEVX_APPLICATION_CHAINING, bFileNo, offset, length, &data, &rlen);
	if(ret){
		LOG2_ERR("Reader_MFDF_ReadData fail: %04X", ret);
		return 6;
	}
	LOG2_BUF_DBG("data:", data, rlen);		
	memcpy(div, data, rlen);
		
	uint8_t end_apdu[] = {0x90, 0xee, 0x00, 0x00, 0x00};
	uint8_t *end_rapdu;
	uint16_t end_rlen;
	phpalI14443p4_Sw_DataParams_t*	ppalI14443p4 = (phpalI14443p4_Sw_DataParams_t *) phNfcLib_GetDataParams(PH_COMP_PAL_ISO14443P4);

	phpalI14443p4_Exchange(ppalI14443p4, PH_EXCHANGE_DEFAULT, end_apdu, sizeof(end_apdu), &end_rapdu, &end_rlen);
//7. DESELECT credential.
	phpalI14443p4_Deselect(ppalI14443p4);
	
	return 0;
}

/*=============================================================*/

TEST_GROUP(ZKTech);


TEST_SETUP(ZKTech)
{
	reader.hfFlags = TAG_MASK_MIFARE;
	Reader_NFC_LoadProfile(reader.hfFlags, 0, 0, 0);
}

TEST_TEAR_DOWN(ZKTech)
{
	Reader_NFC_RfOff();
}



TEST(ZKTech, read)
{
	int ret;	
	credential_t cred;
	//03FFFF
	uint8_t tci[3] = { 0x03, 0xFF, 0xFF };
	apple_epc2_set_tci(tci, 3);
	// apple_epc2_set_terminal_type(0,0);
	while(1){
		Reader_NFC_RfOff();	
		BSP_Sleep_Ms(500);
		ret = Reader_NFC_DiscoveryStd3(&cred.tag, PHAC_DISCLOOP_POS_BIT_MASK_A, 5);
		if(!ret){
			LOG2_BUF_DBG("tag", cred.tag.uid, cred.tag.ulen);
			uint8_t uid[8];
			uint8_t ulen = 0;
			ret = reader_switflane_read_uid(uid, &ulen);
			if(ret){
				continue;
			}
			LOG2_BUF_DBG("uid", uid, ulen);
		}
	}
}


